package com.mystnihon.tdroid.manager;

import java.util.ArrayList;
import java.util.Observable;

import android.content.Context;
import android.content.SharedPreferences;
import android.net.Uri;
import android.preference.PreferenceManager;
import android.util.Log;
import ca.benow.transmission.TransmissionClient;
import ca.benow.transmission.model.AddedTorrentInfo;
import ca.benow.transmission.model.TorrentStatus;

import com.mystnihon.tdroid.R;
import com.mystnihon.tdroid.config.Config;
import com.mystnihon.tdroid.loader.AbstractAsyncLoader.LoadingListener;
import com.mystnihon.tdroid.loader.AddTorrentLoader;
import com.mystnihon.tdroid.loader.GetTorrentsLoader;
import com.mystnihon.tdroid.loader.RemoveTorrentLoader;
import com.mystnihon.tdroid.loader.StartStopTorrentLoader;
import com.mystnihon.tdroid.manager.TransmissionManager.TransmissionResult.ActionType;
import com.mystnihon.tdroid.manager.TransmissionManager.TransmissionResult.ResultType;

public class TransmissionManager extends Observable {

    private static final String TAG = TransmissionManager.class.getSimpleName();
    private Context mContext;
    public TransmissionClient mTransmissionClient;
    private boolean mClientShouldBeInit = true;

    public TransmissionManager(Context context) {
        mContext = context;
    }

    public boolean hasInitClient() {
        if (Config.DEBUG_MODE_ENABLED)
            Log.d(TAG, "Ask if client init. Client init ?:" + (mTransmissionClient != null));
        return mTransmissionClient != null;
    }

    public boolean initTransmissionclient() {
        if (Config.DEBUG_MODE_ENABLED)
            Log.d(TAG, "initTransmission client");

        SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(mContext);

        String host = prefs.getString(mContext.getString(R.string.key_seedbox_host), null);
        if (host != null) {
            int port = Integer.parseInt(prefs.getString(mContext.getString(R.string.key_seedbox_port), "9091"));
            boolean identification = prefs.getBoolean(mContext.getString(R.string.key_seedbox_use_identifiers), false);
            String user = prefs.getString(mContext.getString(R.string.key_seedbox_login), null);
            String pass = prefs.getString(mContext.getString(R.string.key_seedbox_password), null);
            if (identification) {
                mTransmissionClient = new TransmissionClient(host, port, user, pass);
            } else {
                mTransmissionClient = new TransmissionClient(host, port);
            }
            mClientShouldBeInit = false;
            return true;
        }
        return false;
    }

    public boolean IsClientShouldBeInit() {
        return mClientShouldBeInit;
    }

    public void setClientShouldBeInit(boolean shouldReInit) {
        mClientShouldBeInit = shouldReInit; // I set than i should reinit the
                                            // client.
    }

    public void getTorrentList() {
        if (Config.DEBUG_MODE_ENABLED) {
            Log.d(TAG, "get torrent list");
        }
        GetTorrentsLoader loader = new GetTorrentsLoader(mTransmissionClient);
        // setChanged();
        loader.loadAsync(mContext, new LoadingListener<ArrayList<TorrentStatus>>() {

            @Override
            public void onLoadFinished(ArrayList<TorrentStatus> data) {
                setChanged();
                notifyObservers(new TransmissionResult(ResultType.SUCCESS, ActionType.GetTorrent, data));
            }

            @Override
            public void onLoadError(ArrayList<TorrentStatus> data, String errorMessage) {
                setChanged();
                notifyObservers(new TransmissionResult(ResultType.ERROR, ActionType.GetTorrent, data));

            }
        });
    }

    public void startTorrent(int torrentId) {
        if (Config.DEBUG_MODE_ENABLED) {
            Log.d(TAG, "get torrent list");
        }
        startStop(torrentId, true);
    }

    public void stopTorrent(int torrentId) {
        if (Config.DEBUG_MODE_ENABLED) {
            Log.d(TAG, "get torrent list");
        }
        startStop(torrentId, false);
    }

    private void startStop(int torrentId, boolean start) {
        final ActionType action = start ? ActionType.StartTorrent : ActionType.StopTorrent;
        StartStopTorrentLoader loader = new StartStopTorrentLoader(mTransmissionClient, start, torrentId);
        // setChanged();
        loader.loadAsync(mContext, new LoadingListener<Void>() {

            @Override
            public void onLoadFinished(Void data) {
                setChanged();
                notifyObservers(new TransmissionResult(ResultType.SUCCESS, action, data));
            }

            @Override
            public void onLoadError(Void data, String errorMessage) {
                setChanged();
                notifyObservers(new TransmissionResult(ResultType.ERROR, action, data));

            }
        });
    }

    public void removeTorrent(int torrentId, boolean removelocalfile) {
        RemoveTorrentLoader loader = new RemoveTorrentLoader(mTransmissionClient, removelocalfile, torrentId);
        loader.loadAsync(mContext, new LoadingListener<Void>() {

            @Override
            public void onLoadFinished(Void data) {
                setChanged();
                notifyObservers(new TransmissionResult(ResultType.SUCCESS, ActionType.RemoveTorrent, data));

            }

            @Override
            public void onLoadError(Void data, String errorMessage) {
                setChanged();
                notifyObservers(new TransmissionResult(ResultType.ERROR, ActionType.RemoveTorrent, data));

            }

        });
    }

    public void addTorrent(Uri torrent) {
        if (Config.DEBUG_MODE_ENABLED) {
            Log.d(TAG, "Add torrent :" + torrent);
        }
        AddTorrentLoader loader = new AddTorrentLoader(mTransmissionClient, torrent);
        loader.loadAsync(mContext, new LoadingListener<AddedTorrentInfo>() {

            @Override
            public void onLoadFinished(AddedTorrentInfo data) {
                setChanged();
                notifyObservers(new TransmissionResult(ResultType.SUCCESS, ActionType.RemoveTorrent, data));

            }

            @Override
            public void onLoadError(AddedTorrentInfo data, String errorMessage) {
                setChanged();
                notifyObservers(new TransmissionResult(ResultType.ERROR, ActionType.RemoveTorrent, data));

            }

        });
    }

    public static class TransmissionResult {
        public enum ResultType {
            SUCCESS, ERROR

        }

        public enum ActionType {
            GetTorrent, StartTorrent, StopTorrent, RemoveTorrent
        }

        public ResultType mSuccess;
        public Object mData;
        public ActionType mAction;

        public TransmissionResult(ResultType success, ActionType action, Object data) {
            mSuccess = success;
            mAction = action;
            mData = data;
        }
    }
}
